{
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# Intro to Flux.jl"
      ],
      "metadata": {}
    },
    {
      "cell_type": "markdown",
      "source": [
        "We have learned how machine learning allows us to classify data as apples or bananas with a single neuron. However, some of those details are pretty fiddly! Fortunately, Julia has a powerful package that does much of the heavy lifting for us, called [`Flux.jl`](https://fluxml.github.io/).\n\n*Using `Flux` will make classifying data and images much easier!*"
      ],
      "metadata": {}
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Using `Flux.jl`\n\nIn the next notebook, we are going to see how Flux allows us to redo the calculations from the previous notebook in a simpler way. We can get started with `Flux.jl` via:"
      ],
      "metadata": {}
    },
    {
      "outputs": [],
      "cell_type": "code",
      "source": [
        "using Flux"
      ],
      "metadata": {},
      "execution_count": null
    },
    {
      "cell_type": "markdown",
      "source": [
        "#### Helpful built-in functions\n\nWhen working we'll `Flux`, we'll make use of built-in functionality that we've had to create for ourselves in previous notebooks.\n\nFor example, the sigmoid function, σ, that we have been using already lives within `Flux`:"
      ],
      "metadata": {}
    },
    {
      "outputs": [],
      "cell_type": "code",
      "source": [
        "?σ"
      ],
      "metadata": {},
      "execution_count": null
    },
    {
      "cell_type": "markdown",
      "source": [
        "Importantly, `Flux` allows us to *automatically create neurons* with the **`Dense`** function. For example, in the last notebook, we were looking at a neuron with 2 inputs and 1 output:\n \n <img src=\"data/single-neuron.png\" alt=\"Drawing\" style=\"width: 500px;\"/>\n \n We could create a neuron with two inputs and one output via"
      ],
      "metadata": {}
    },
    {
      "outputs": [],
      "cell_type": "code",
      "source": [
        "model = Dense(2, 1, σ)"
      ],
      "metadata": {},
      "execution_count": null
    },
    {
      "cell_type": "markdown",
      "source": [
        "This `model` object comes with places to store weights and biases:"
      ],
      "metadata": {}
    },
    {
      "outputs": [],
      "cell_type": "code",
      "source": [
        "model.W"
      ],
      "metadata": {},
      "execution_count": null
    },
    {
      "outputs": [],
      "cell_type": "code",
      "source": [
        "model.b"
      ],
      "metadata": {},
      "execution_count": null
    },
    {
      "outputs": [],
      "cell_type": "code",
      "source": [
        "typeof(model.W)"
      ],
      "metadata": {},
      "execution_count": null
    },
    {
      "cell_type": "markdown",
      "source": [
        "Unlike in previous notebooks, note that `W` is no longer a `Vector` (1D `Array`) and `b` is no longer a number! Both are now stored in so-called `TrackedArray`s and `W` is effectively being treated as a matrix with a single row. We'll see why in the next notebook."
      ],
      "metadata": {}
    },
    {
      "outputs": [],
      "cell_type": "code",
      "source": [
        ""
      ],
      "metadata": {},
      "execution_count": null
    },
    {
      "cell_type": "markdown",
      "source": [
        "Other helpful built-in functionality includes ways to automatically calculate gradients and also the cost function that we've used in previous notebooks - \n\n$$L(w, b) = \\sum_i \\left[y_i - f(x_i, w, b) \\right]^2$$\n\nThis is the \"mean square error\" function, which in `Flux` is named **`Flux.mse`**."
      ],
      "metadata": {}
    }
  ],
  "nbformat_minor": 2,
  "metadata": {
    "language_info": {
      "file_extension": ".jl",
      "mimetype": "application/julia",
      "name": "julia",
      "version": "0.6.2"
    },
    "kernelspec": {
      "name": "julia-0.6",
      "display_name": "Julia 0.6.2",
      "language": "julia"
    }
  },
  "nbformat": 4
}
